import { LngLat } from '../entity/lngLat'
import { Point } from '../entity/point'

import { Overlay } from './overlay'
import { DefinedOverlayTypeEnum } from './enum'

/**
 * 信息窗的属性对象
 */
export interface InfoWindowOptions {
    /**
     * 弹出框的最小宽度
     *
     * 默认值为 `50`
     */
    minWidth?: number;

    /**
     * 弹出框的最大宽度
     *
     * 默认值为 `300`
     */
    maxWidth?: number;

    /**
     * 设置后，如果内容超过弹出窗口的给定高度则产生一个可以滚动的容器
     *
     * 默认值为 `null`
     */
    maxHeight?: number;

    /**
     * 是否开启信息窗口打开时地图自动移动（默认关闭）
     *
     * 默认值为 `false`
     */
    autoPan?: boolean;

    /**
     * 控制弹出窗口中出现的关闭按钮
     *
     * 默认值为 `true`
     */
    closeButton?: boolean;

    /**
     * 弹出窗口位置的补偿值。在同一图层中打开弹出窗口时对于控制锚点比较有用
     *
     * 默认值为 `Point(0, 7)`
     */
    offset?: Point;

    /**
     * 在地图视图自动平移产生后弹出窗口和地图视图之间的边缘
     *
     * 默认值为 `Point(5, 5)`
     */
    autoPanPadding?: Point;

    /**
     * 是否开启点击地图关闭信息窗口（默认关闭）
     *
     * 默认值为 `false`
     */
    closeOnClick?: boolean
}

/**
 * 信息窗事件工厂对象
 */
type InfoWindowEventFactory = {
    /**
     * 信息窗口被关闭时触发此事件
     */
    close: (event: { type: 'close', target: InfoWindow, lnglat: LngLat }) => void;

    /**
     * 信息窗口被打开时触发此事件
     */
    open: (event: { type: 'open', target: InfoWindow, lnglat: LngLat }) => void;

    /**
     * 点击信息窗口的关闭按钮时触发此事件
     */
    clickclose: (event: { type: 'clickclose', target: InfoWindow }) => void
}

/**
 * 此类表示地图上包含信息的窗口
 */
export interface InfoWindow extends Overlay {
    readonly options: InfoWindowOptions;

    /**
     * 创建一个信息窗实例
     *
     * @param content 信息窗的内容，可以是字符串或 `HTMLElement` 对象
     *
     * @param opts 信息窗的属性对象
     */
    new(content: string | HTMLElement, opts?: InfoWindowOptions): InfoWindow;

    /**
     * 叠加层类型
     */
    getType: () => DefinedOverlayTypeEnum.InfoWindow;

    /**
     * 返回信息浮窗所指向的地理位置坐标
     */
    getLngLat: () => LngLat;
    /**
     * 设置或改变信息浮窗所指向的地理位置坐标
     *
     * @param lnglat 地理位置坐标
     */
    setLngLat: (lnglat: LngLat) => void;

    /**
     * 返回信息浮窗显示时向右下角偏移量
     */
    getOffset: () => Point;
    /**
     * 设置信息浮窗显示时向右下角偏移量（像素）
     *
     * @param point 偏移量（像素）
     */
    setOffset: (point: Point) => void;

    /**
     * 返回信息窗口的打开状态
     */
    isOpen: () => boolean;

    /**
     * 返回信息浮窗的显示 `HTML` 内容
     */
    getContent: () => string | HTMLElement;
    /**
     * 设置信息浮窗的显示 HTML 内容
     *
     * @param content 信息浮窗的内容，可以是 `HTML` 字符串或 `HTMLElement` 对象
     */
    setContent: (content: string | HTMLElement) => void;

    /**
     * 重绘信息窗口，当信息窗口内容发生变化时进行调用
     */
    update: () => void;

    /**
     * 关闭信息浮窗
     */
    closeInfoWindow: () => void;

    /**
     * 添加事件监听函数
     */
    addEventListener: <Event extends keyof InfoWindowEventFactory>(event: Event, handler: InfoWindowEventFactory[Event]) => void;
    
    /**
     * 移除事件监听函数
     */
    removeEventListener: <Event extends keyof InfoWindowEventFactory>(event: Event, handler: InfoWindowEventFactory[Event]) => void
}
